package com.jpa.sgcrm;

import java.io.Serializable;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Iterator;
import java.util.ResourceBundle;

import com.jpa.model.Company;
import com.jpa.model.Income;
import com.vaadin.addon.jpacontainer.JPAContainer;
import com.vaadin.data.Item;
import com.vaadin.data.validator.BeanValidator;
import com.vaadin.event.FieldEvents.FocusEvent;
import com.vaadin.event.FieldEvents.FocusListener;
import com.vaadin.event.FieldEvents.TextChangeEvent;
import com.vaadin.event.FieldEvents.TextChangeListener;
import com.vaadin.server.Page;
import com.vaadin.shared.Position;
import com.vaadin.ui.AbstractSelect.NewItemHandler;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.ComboBox;
import com.vaadin.ui.Component;
import com.vaadin.ui.DefaultFieldFactory;
import com.vaadin.ui.Field;
import com.vaadin.ui.Form;
import com.vaadin.ui.FormFieldFactory;
import com.vaadin.ui.NativeSelect;
import com.vaadin.ui.Notification;
import com.vaadin.ui.Notification.Type;
import com.vaadin.ui.PopupDateField;
import com.vaadin.ui.TextField;
import com.vaadin.ui.Window;

@SuppressWarnings({ "serial", "deprecation" })
public class Editor extends Window implements Button.ClickListener,
		FormFieldFactory {

	private final Item personItem;
	private Form editorForm;
	private Button saveButton;
	private Button cancelButton;
	boolean isIncome;
	public JPAContainer<TypeIn> con;
	public JPAContainer<TypeOut> con1;
	public JPAContainer<Company> company;
	public ResourceBundle Messages;
	
	public Editor(Item personItem, boolean isIncome, JPAContainer<TypeIn> con,
			JPAContainer<TypeOut> con1, JPAContainer<Company> company, ResourceBundle Messages) {
		this.personItem = personItem;
		this.isIncome = isIncome;
		this.Messages = Messages;
		this.company = company;
		this.con = con;
		this.con1 = con1;
		editorForm = new Form();
		editorForm.setFormFieldFactory(this);
		editorForm.setBuffered(true);
		editorForm.setImmediate(true);
		editorForm.setItemDataSource(personItem, Arrays.asList("month", "type", //$NON-NLS-1$ //$NON-NLS-2$
				"name", "company", "date", "paid", "price", "vat", "total","phone","address","companyOption")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$

		saveButton = new Button(Messages.getString("Editor.save"), this); //$NON-NLS-1$
		cancelButton = new Button(Messages.getString("Editor.cancel"), this); //$NON-NLS-1$

		editorForm.getFooter().addComponent(saveButton);
		editorForm.getFooter().addComponent(cancelButton);
		setSizeUndefined();
		setContent(editorForm);
		setCaption(buildCaption());
	}

	/**
	 * @return the caption of the editor window
	 */
	private String buildCaption() {
		return String.format("%s ", personItem.getItemProperty("name") //$NON-NLS-1$ //$NON-NLS-2$
				.getValue()); //$NON-NLS-1$
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.vaadin.ui.Button.ClickListener#buttonClick(com.vaadin.ui.Button.
	 * ClickEvent)
	 */
	@SuppressWarnings({ "unchecked" })
	@Override
	public void buttonClick(ClickEvent event) {
		if (event.getButton() == saveButton) {

			editorForm.commit();
			if(personItem.getItemProperty("price")!=null){
				
			int price = (Integer) personItem.getItemProperty("price") //$NON-NLS-1$
					.getValue();
			if (personItem.getItemProperty("vat").getValue().equals(0)) { //$NON-NLS-1$
				// System.out.println("when 0");
				int vat = price / 10;
				personItem.getItemProperty("vat").setValue(vat); //$NON-NLS-1$
				int total = price + vat;
				personItem.getItemProperty("total").setValue(total); //$NON-NLS-1$
			} else {
				// System.out.println("when not 0");

				int vat = (Integer) personItem.getItemProperty("vat") //$NON-NLS-1$
						.getValue();
				personItem.getItemProperty("total").setValue(price + vat); //$NON-NLS-1$

			}
			// System.out.println(personItem.getItemProperty("total").getValue());
			}
			fireEvent(new EditorSavedEvent(this, personItem));
			editorForm.commit();
		} else if (event.getButton() == cancelButton) {
			editorForm.discard();
		}
		close();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.vaadin.ui.FormFieldFactory#createField(com.vaadin.data.Item,
	 * java.lang.Object, com.vaadin.ui.Component)
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	@Override
	public Field createField(Item item, Object propertyId, Component uiContext) {
		Field field = DefaultFieldFactory.get().createField(item, propertyId,
				uiContext);
		if ("price".equals(propertyId)) { //$NON-NLS-1$
			TextField t = new TextField("PRICE"); //$NON-NLS-1$
			t.setCaption(Messages.getString("Editor.price")); //$NON-NLS-1$
			t.setNullRepresentation("");
			t.addFocusListener(new FocusListener(){
			
				
				@Override
				public void focus(FocusEvent event) {
					// TODO Auto-generated method stub
					Notification nf = new Notification("Auto adds 10% of vat. change vat to customize vat",Type.TRAY_NOTIFICATION);
					nf.setPosition(Position.MIDDLE_CENTER);
					nf.setDelayMsec(100);
					nf.show(Page.getCurrent());
				}	
				
			});
			field = t;
		} else if ("month".equals(propertyId)) { //$NON-NLS-1$
			NativeSelect c = new NativeSelect();
			for (int i = 1; i <= 12; i++) {
				c.addItem(i);
			}
			c.setCaption(Messages.getString("Editor.month")); //$NON-NLS-1$

			field = c;

		} else if ("date".equals(propertyId)) { //$NON-NLS-1$
			PopupDateField date = null;
			date = new PopupDateField("date"); //$NON-NLS-1$
			date.setDateFormat("MM-dd-yyyy"); //$NON-NLS-1$
			date.setLenient(false);
			date.setCaption(Messages.getString("Editor.date")); //$NON-NLS-1$
			field = date;

		} else if ("paid".equals(propertyId)) { //$NON-NLS-1$
			PopupDateField date = null;
			date = new PopupDateField("paid"); //$NON-NLS-1$
			date.setDateFormat("MM-dd-yyyy"); //$NON-NLS-1$
			date.setLenient(false);
			date.setCaption(Messages.getString("Editor.paid")); //$NON-NLS-1$
			field = date;
		} else if ("type".equals(propertyId)) { //$NON-NLS-1$
			// System.out.println(isIncome);

			if (isIncome) {
				final ComboBox ns = new ComboBox(
						Messages.getString("Editor.type")); //$NON-NLS-1$

				con.addEntity(new TypeIn(1, "Project")); //$NON-NLS-1$
				con.addEntity(new TypeIn(2, "National Agenda")); //$NON-NLS-1$

				Iterator<?> it = con.getItemIds().iterator();
				while (it.hasNext()) {
					ns.addItems(con
							.getContainerProperty(it.next(), "type").getValue()); //$NON-NLS-1$
				}
				ns.setInputPrompt(Messages.getString("Editor.select")); //$NON-NLS-1$
				ns.setNewItemsAllowed(true);
				ns.setImmediate(true);
				ns.setNewItemHandler(new NewItemHandler() {

					@Override
					public void addNewItem(String newItemCaption) {
						// TODO Auto-generated method stub
						TypeIn newType = new TypeIn(0, newItemCaption);
						con.addEntity(newType);
						ns.addItem(newItemCaption);
						ns.select(newItemCaption);
						Notification.show(Messages.getString("Editor.new")); //$NON-NLS-1$

					}

				});
				field = ns;
			} else {

				final ComboBox ns = new ComboBox(
						Messages.getString("Editor.type")); //$NON-NLS-1$
				con1.addEntity(new TypeOut(1, "General")); //$NON-NLS-1$
				con1.addEntity(new TypeOut(2, "Labor Costs")); //$NON-NLS-1$
				con1.addEntity(new TypeOut(3, "Retirement Pension")); //$NON-NLS-1$
				con1.addEntity(new TypeOut(4, "Insurance")); //$NON-NLS-1$
				con1.addEntity(new TypeOut(5, "PAE System")); //$NON-NLS-1$
				con1.addEntity(new TypeOut(6, "National Treasury")); //$NON-NLS-1$
				con1.addEntity(new TypeOut(7, "Corporation Tax")); //$NON-NLS-1$
				Iterator<?> it = con1.getItemIds().iterator();
				while (it.hasNext()) {
					ns.addItems(con1
							.getContainerProperty(it.next(), "type").getValue()); //$NON-NLS-1$
				}
				ns.setInputPrompt(Messages.getString("Editor.select")); //$NON-NLS-1$
				ns.setNewItemsAllowed(true);
				ns.setImmediate(true);
				ns.setNewItemHandler(new NewItemHandler() {

					@Override
					public void addNewItem(String newItemCaption) {
						// TODO Auto-generated method stub
						TypeOut newType = new TypeOut(0, newItemCaption);
						con1.addEntity(newType);
						ns.addItem(newItemCaption);
						ns.select(newItemCaption);
						Notification.show(Messages.getString("Editor.new")); //$NON-NLS-1$

					}

				});
				field = ns;

			}
		} else if ("name".equals(propertyId)) { //$NON-NLS-1$
			TextField t = new TextField();
			t.setCaption(Messages.getString("Editor.name")); //$NON-NLS-1$
			t.setNullRepresentation("");
			field = t;
		} else if ("company".equals(propertyId)) { //$NON-NLS-1$
			final ComboBox t = new ComboBox();
			Iterator<?> it = company.getItemIds().iterator();
			while(it.hasNext()){
				t.addItem(company.getContainerProperty(it.next(), "companyOption").getValue());
			}
			t.setImmediate(true);
			t.setCaption(Messages.getString("Editor.company")); //$NON-NLS-1$
			field = t;
		} else if ("vat".equals(propertyId)) { //$NON-NLS-1$
			TextField t = new TextField();
			t.setCaption(Messages.getString("Editor.vat")); //$NON-NLS-1$
			t.setNullRepresentation("");
			field = t;
		} else if ("total".equals(propertyId)) { //$NON-NLS-1$
			TextField t = new TextField();
			t.setCaption(Messages.getString("Editor.total")); //$NON-NLS-1$
			t.setNullRepresentation("");
			field = t;
		}
		else if("companyOption".equals(propertyId)){
			TextField t = new TextField();
			t.setCaption(Messages.getString("Editor.company"));
			t.setNullRepresentation("");
			field = t;
		}

		else if (field instanceof TextField) {
			((TextField) field).setNullRepresentation(""); //$NON-NLS-1$
		}
		field.addValidator(new BeanValidator(Income.class, propertyId
				.toString()));

		return field;
	}

	public void addListener(EditorSavedListener listener) {
		try {
			Method method = EditorSavedListener.class.getDeclaredMethod(
					"editorSaved", new Class[] { EditorSavedEvent.class }); //$NON-NLS-1$
			addListener(EditorSavedEvent.class, listener, method);
		} catch (final java.lang.NoSuchMethodException e) {
			// This should never happen
			throw new java.lang.RuntimeException(
					"Internal error, editor saved method not found"); //$NON-NLS-1$
		}
	}

	public void removeListener(EditorSavedListener listener) {
		removeListener(EditorSavedEvent.class, listener);
	}

	public static class EditorSavedEvent extends Component.Event {

		private Item savedItem;

		public EditorSavedEvent(Component source, Item savedItem) {
			super(source);
			this.savedItem = savedItem;
		}

		public Item getSavedItem() {
			return savedItem;
		}
	}

	public interface EditorSavedListener extends Serializable {
		public void editorSaved(EditorSavedEvent event);
	}

}
